/*
 * CgStatement.c
 *
 *  Created on: 2012/06/07
 *      Author: guanxiaoying
 */

#include "../coredef.h"
#include "../cc/cc.h"
#include "cg.h"


static CG_RESULT cg_Statement( AST, BOOL );
static AST cg_AddConfluxStack( AST astNode, U2 kind ){
	AST astNew;
	stCgConfluxNodeStackAccess.alloc(1);
	astNew = stCgConfluxNodeStackAccess.getMax();
	stCgConfluxNodeStackAccess.flownode.set( astNew, astNode );
	stCgConfluxNodeStackAccess.kind.set( astNew, kind );
	return astNew;
}
static VOID cg_DelConfluxStack( VOID ){
	stCgConfluxNodeStackAccess.alloc(1);
}
static VOID cg_recordResult( CG_RESULT result, AST astStmt ){
	stStatementAccess.begin.set( astStmt, result.astBegin );
	stStatementAccess.end.set( astStmt, result.astEnd );
}
static CG_RESULT cg_ExpStatement( AST astStmt, BOOL bSideEffect ){
	AST astExp = stStatementAccess.exp_exp.get( astStmt );
	AST astCmdList;
	AST astOperand;
	CG_RESULT result={0,0};
	CG_RESULT resultIncDec={0,0};
	TRY;
	/* start  */
	/* body */
	result = CG_Expression( astExp, bSideEffect );
	resultIncDec = CG_ExpPullPostIncDec(TRUE);
	result = CG_MergeResult( result, resultIncDec );
	if( bSideEffect == FALSE ){
		astCmdList = CG_NewCmdListByKind( ASM_CMD_NOP, astExp );
	}else{
		astCmdList = CG_NewCmdListByKind( ASM_CMD_GETOPERAND, astExp );
		astOperand = CG_NewResultOperand( result.astEnd );
		stCmdListAccess.leftOperand.set( astCmdList, astOperand );
	}
	result = CG_MergeCmdList( result, astCmdList );
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_LabelStatement( AST astStmt, BOOL bSideEffect ){
	AST astChildStmt;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	TRY;
	result.astBegin = stStatementAccess.begin.get( astStmt );
	if( result.astBegin == 0 ){
		result.astBegin = CG_NewConfluxCmdList( astStmt, "_conflux" );
		result.astEnd = result.astBegin;
		cg_recordResult( result, astStmt );
	}else{
		result.astEnd = result.astBegin;
	}
	astChildStmt = stStatementAccess.label_statement.get( astStmt );
	result_child = cg_Statement( astChildStmt, bSideEffect );
	result = CG_MergeResult( result, result_child );
	CATCH( result );
	return result;
}
static CG_RESULT cg_CaseStatement( AST astStmt, BOOL bSideEffect ){
	AST astChildStmt;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	TRY;
	result.astBegin = stStatementAccess.begin.get( astStmt );
	if( result.astBegin == 0 ){
		result.astBegin = CG_NewConfluxCmdList( astStmt, "_conflux" );
		result.astEnd = result.astBegin;
		cg_recordResult( result, astStmt );
	}
	astChildStmt = stStatementAccess.case_statement.get( astStmt );
	result_child = cg_Statement( astChildStmt, bSideEffect );
	result = CG_MergeResult( result, result_child );
	CATCH( result );
	return result;
}
static CG_RESULT cg_DefaultStatement( AST astStmt, BOOL bSideEffect ){
	AST astChildStmt;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	TRY;
	result.astBegin = stStatementAccess.begin.get( astStmt );
	if( result.astBegin == 0 ){
		result.astBegin = CG_NewConfluxCmdList( astStmt, "_conflux" );
		result.astEnd = result.astBegin;
		cg_recordResult( result, astStmt );
	}
	astChildStmt = stStatementAccess.default_statement.get( astStmt );
	result_child = cg_Statement( astChildStmt, bSideEffect );
	result = CG_MergeResult( result, result_child );
	CATCH( result );
	return result;
}
static CG_RESULT cg_BlockStatement( AST astStmt, BOOL bSideEffect ){
	AST astChildStmt, astChildStmt2;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	TRY;
	/* start */
//	result.astBegin  = CG_NewStartingCmdList( astStmt);
//	result.astEnd = result.astBegin;
	/* body */
	astChildStmt = stStatementAccess.block_stmtlist.get( astStmt );
	while( astChildStmt ){
		astChildStmt2 = stStatementAccess.next.get( astChildStmt );
		if( astChildStmt2 > 0 ){
			result_child = cg_Statement( astChildStmt, FALSE );
		}else{
			result_child = cg_Statement( astChildStmt, bSideEffect );
		}
		result = CG_MergeResult( result, result_child);
		astChildStmt = astChildStmt2;
	}
	/* end */
//	result_child.astBegin = CG_NewEndingCmdList( astStmt);
//	result = CG_MergeCmdList( result, result_child.astBegin);
	/* record */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_IfStatement( AST astStmt, BOOL bSideEffect ){
	AST astChildStmt;
	AST astCmdList;
	AST astBrCmdList;
	AST astOperand;
	AST astExp;
	AST astConfluxCmdList;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	CG_RESULT result_IncDec={0,0};
	CG_RESULT result_body={0,0};
	TRY;
		/* condition expression */
	astExp = stStatementAccess.if_condExp.get( astStmt );
	result = CG_Expression( astExp, TRUE );
	if( result.astBegin > 0 ){
		astCmdList = CG_NewJudgeCmdList( astExp );
		astOperand = CG_NewResultOperand( result.astEnd );
		stCmdListAccess.leftOperand.set( astCmdList, astOperand );
		result = CG_MergeCmdList( result, astCmdList );
	}
		/* branch point */
	astBrCmdList = CG_NewBranchCmdList( astStmt );
		/* conflux point */
	astConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux" );
//	astOperand = CG_NewResultOperand( astConfluxCmdList );
//	stCmdListAccess.outputOperand.set( astBrCmdList, astOperand );

	result = CG_MergeCmdList( result, astBrCmdList );

	result_child = CG_ExpPullPostIncDec(FALSE);
	result_IncDec = CG_ExpPullPostIncDec(TRUE);
		/* if body */
	astChildStmt = stStatementAccess.if_body.get( astStmt );
	result_body = cg_Statement( astChildStmt, FALSE );
	result_body = CG_MergeResult( result_child, result_body );
	result_body = CG_MergeCmdList( result_body, astConfluxCmdList );
	astOperand = CG_NewResultOperand( result_body.astBegin );
	stCmdListAccess.leftOperand.set( astBrCmdList, astOperand );

		/* else body */
	astChildStmt = stStatementAccess.if_else_body.get( astStmt );
	if( astChildStmt > 0 ){
		result_body = cg_Statement( astChildStmt, FALSE );
		result_body = CG_MergeResult( result_IncDec, result_body );

	}else{
		result_body = result_IncDec;
	}
	result_body = CG_MergeCmdList( result_body, astConfluxCmdList );
	astOperand = CG_NewResultOperand( result_body.astBegin );
	stCmdListAccess.rightOperand.set( astBrCmdList, astOperand );
	/* end */
	result = CG_MergeCmdList( result, astConfluxCmdList );
//	result.astEnd = astConfluxCmdList;
	/* record */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_SwitchStatement( AST astStmt, BOOL bSideEffect ){
	AST astCondCmdListEnd=0;
	AST astCmdList=0;
	AST astBreakConfluxCmdList;
	AST astOperand;
	AST astBranchCmdList;
	AST astPreBranchCmdList = 0;
	AST astPreConfluxCmdList = 0;
	AST astExp;
	AST astCaseStmt;
	AST astDefaultStmt;
	AST astSwitchBody;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	CG_RESULT result_body={0,0};

	BOOL bFirstCase = TRUE;
	TRY;
		/* condition expression */
	astExp = stStatementAccess.switch_condExp.get( astStmt );
	result = CG_Expression( astExp, TRUE );
		/* conflux point */
	astBreakConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux" );
	cg_AddConfluxStack( astBreakConfluxCmdList, STMT_BREAK );

	astSwitchBody = stStatementAccess.switch_body.get( astStmt );
	result_body = cg_Statement( astSwitchBody, FALSE );
	result_body = CG_MergeCmdList( result_body, astBreakConfluxCmdList );
	astCaseStmt = stStatementAccess.switch_firstCase.get( astStmt );
	astDefaultStmt = stStatementAccess.switch_default.get( astStmt );
	if( result.astBegin == 0 ){
		;
	}else if( astCaseStmt == 0 && astDefaultStmt > 0 ){
		result_child = CG_ExpPullPostIncDec(TRUE);
		result_body.astBegin = stStatementAccess.begin.get( astDefaultStmt );
		result_body = CG_MergeCmdList( result_child, result_body.astBegin );
		if( result_body.astBegin == 0 ){
			/* impossible path */
			result_body.astBegin = astBreakConfluxCmdList;
		}
		result = CG_MergeCmdList( result, result_body.astBegin );
		result = CG_MergeCmdList( result, astBreakConfluxCmdList );
	}else if( astCaseStmt > 0 ){

		while( astCaseStmt ){
			/* condition  */
			astExp = stStatementAccess.case_constExp.get( astCaseStmt );
			result_child = CG_AddExpression( result.astEnd, ASM_CMD_EQUAL, astExp );
			if( result_child.astBegin > 0 ){
				if( bFirstCase ){
					result = CG_MergeResult( result, result_child );
					bFirstCase = FALSE;
				}
				astCondCmdListEnd = result_child.astEnd;
			}
			astOperand = CG_NewResultOperand( astCondCmdListEnd );
			astCmdList = CG_NewJudgeCmdList( astExp );
			stCmdListAccess.leftOperand.set( astCmdList, astOperand );
			result_child = CG_MergeCmdList( result_child, astCmdList );
			astBranchCmdList = CG_NewBranchCmdList( astCaseStmt );
			result_child = CG_MergeCmdList( result_child, astBranchCmdList );
			if( astPreConfluxCmdList == 0 ){
				stCmdListAccess.next.set( astBranchCmdList, astBreakConfluxCmdList );
				stCmdListAccess.before.set( astBreakConfluxCmdList, astBranchCmdList );
				astPreConfluxCmdList = astBreakConfluxCmdList;
			}else{
				astCmdList = CG_NewConfluxCmdList( astCaseStmt, "_conflux" );
				stCmdListAccess.next.set( astBranchCmdList, astCmdList );
				stCmdListAccess.before.set( astCmdList, astBranchCmdList );
				stCmdListAccess.next.set( astCmdList, astPreConfluxCmdList );
				astPreConfluxCmdList = astCmdList;
			}

			if( astPreBranchCmdList != 0 ){
				astOperand = CG_NewResultOperand( result_child.astBegin );
				stCmdListAccess.rightOperand.set( astPreBranchCmdList, astOperand );
			}
			astPreBranchCmdList = astBranchCmdList;

			result_child = CG_ExpPullPostIncDec(FALSE);

			result_body.astBegin = stStatementAccess.begin.get( astCaseStmt );
			result_body = CG_MergeCmdList( result_child, result_body.astBegin );
			astOperand = CG_NewResultOperand( result_body.astBegin );
			stCmdListAccess.leftOperand.set( astBranchCmdList, astOperand );
			astCaseStmt = stStatementAccess.case_nextCase.get( astCaseStmt );
		}
		/* default */
		if( astDefaultStmt > 0 ){
			result_body.astBegin = stStatementAccess.begin.get( astDefaultStmt );
		}else{
			result_body.astBegin = 0;
		}
		result_child = CG_ExpPullPostIncDec(TRUE);
		result_body = CG_MergeCmdList( result_child, result_body.astBegin );
		astOperand = CG_NewResultOperand( result_body.astBegin );
		stCmdListAccess.rightOperand.set( astPreBranchCmdList, astOperand );
		/*debug,12/10/16,S*/
//		result = CG_MergeCmdList( result, astBreakConfluxCmdList );
		result.astEnd = astBreakConfluxCmdList;
		/*debug,12/10/16,E*/
	}else{
		result_child = CG_ExpPullPostIncDec(TRUE);
		result_child = CG_MergeCmdList( result_child, astBreakConfluxCmdList );
		result = CG_MergeResult( result, result_child );
	}
	cg_DelConfluxStack();
	/* record */
	cg_recordResult( result, astStmt );

	CATCH( result );
	return result;
}
static CG_RESULT cg_ForStatement( AST astStmt, BOOL bSideEffect ){
	AST astDecl;
	AST astExp;
	AST astChildStmt;
	AST astCmdList=0;
	AST astBreakConfluxCmdList;
	AST astCondConfluxCmdList;
	AST astContinueConfluxCmdList;
//	AST astStack;
	AST astOperand;
	AST astBrCmdList;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	CG_RESULT result_body={0,0};
	TRY;
	/* body */
	astDecl = stStatementAccess.for_Init_Decl.get( astStmt );
	if( astDecl != 0 ){
		result = CG_Declaration( astDecl );
	}else{
		astExp = stStatementAccess.for_initExp.get( astStmt );
		result = CG_Expression( astExp, FALSE );
		result_child = CG_ExpPullPostIncDec(TRUE);
		result = CG_MergeResult( result, result_child );
	}

	astCondConfluxCmdList = CG_NewConfluxCmdList( astStmt , "_conflux_start");
	astContinueConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux_continue" );
	astBreakConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux_break" );

	result = CG_MergeCmdList( result, astCondConfluxCmdList );

	astExp = stStatementAccess.for_CondExp.get( astStmt );
	if( astExp == 0 ){
		AST astConstant = CG_ConvertConstant( CcValueGetOne( CcTypeGetBasicType( "int", 0 )) );
		astOperand = CG_NewConstantOperand( astConstant );
		result_child.astBegin = CG_NewCmdListByKind( ASM_CMD_GETOPERAND, 0 );
		stCmdListAccess.codeScp.set( result_child.astBegin, stStatementAccess.codeScp.get( astStmt ));
		stCmdListAccess.leftOperand.set( result_child.astBegin, astOperand );
		result_child.astEnd = result_child.astBegin;
	}else{
		result_child = CG_Expression( astExp, TRUE );
	}
	result = CG_MergeResult( result, result_child );

		/* branch point */
	astOperand = CG_NewResultOperand( result_child.astEnd );
	astCmdList = CG_NewJudgeCmdList( astExp );
	stCmdListAccess.leftOperand.set( astCmdList, astOperand );
	result = CG_MergeCmdList( result, astCmdList );

	astBrCmdList = CG_NewBranchCmdList( astStmt );
	result = CG_MergeCmdList( result, astBrCmdList );

	result_child = CG_ExpPullPostIncDec(FALSE);
	result_child = CG_MergeCmdList( result_child, astBreakConfluxCmdList );
	astOperand = CG_NewResultOperand( result_child.astBegin );
	stCmdListAccess.rightOperand.set( astBrCmdList, astOperand );

	result_child = CG_ExpPullPostIncDec(TRUE);
	astChildStmt = stStatementAccess.for_Body.get( astStmt );
	/*astStack =*/ cg_AddConfluxStack( astBreakConfluxCmdList, STMT_BREAK );
	/*astStack =*/ cg_AddConfluxStack( astContinueConfluxCmdList, STMT_CONTINUE );
	result_body = cg_Statement( astChildStmt, FALSE );
	cg_DelConfluxStack();
	cg_DelConfluxStack();

	result_body = CG_MergeResult( result_child, result_body );
	result_body = CG_MergeCmdList( result_body, astContinueConfluxCmdList );

	astExp = stStatementAccess.for_IncExp.get( astStmt );
	result_child = CG_Expression( astExp, FALSE );
	result_body = CG_MergeResult( result_body, result_child );
	result_child = CG_ExpPullPostIncDec(TRUE);
	result_body = CG_MergeResult( result_body, result_child );
	result_body = CG_MergeCmdList( result_body, astCondConfluxCmdList );

	astOperand = CG_NewResultOperand( result_body.astBegin );
	stCmdListAccess.leftOperand.set( astBrCmdList, astOperand );

	result = CG_MergeCmdList( result, astBreakConfluxCmdList );
	/* record  */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_WhileStatement( AST astStmt, BOOL bSideEffect ){
	AST astExp;
	AST astChildStmt;
	AST astCmdList=0;
	AST astBreakConfluxCmdList;
	AST astCondConfluxCmdList;
	AST astContinueConfluxCmdList;
//	AST astStack;
	AST astOperand;
	AST astBrCmdList;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	CG_RESULT result_body={0,0};
	TRY;
	astCondConfluxCmdList = CG_NewConfluxCmdList( astStmt , "_conflux_start");
	astContinueConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux_continue" );
	astBreakConfluxCmdList = CG_NewConfluxCmdList( astStmt, "_conflux_break" );

	result.astBegin = astCondConfluxCmdList;
	result.astEnd = astCondConfluxCmdList;

	astExp = stStatementAccess.while_condExp.get( astStmt );
	result_child = CG_Expression( astExp, TRUE );
	result = CG_MergeResult( result, result_child );

		/* branch point */
	astOperand = CG_NewResultOperand( result_child.astEnd );
	astCmdList = CG_NewJudgeCmdList( astExp );
	stCmdListAccess.leftOperand.set( astCmdList, astOperand );
	result = CG_MergeCmdList( result, astCmdList );

	astBrCmdList = CG_NewBranchCmdList( astStmt );
	result = CG_MergeCmdList( result, astBrCmdList );

	result_child = CG_ExpPullPostIncDec(FALSE);
	result_child = CG_MergeCmdList( result_child, astBreakConfluxCmdList );
	astOperand = CG_NewResultOperand( result_child.astBegin );
	stCmdListAccess.rightOperand.set( astBrCmdList, astOperand );

	result_child = CG_ExpPullPostIncDec(TRUE);
	astChildStmt = stStatementAccess.while_body.get( astStmt );
	/*astStack =*/ cg_AddConfluxStack( astBreakConfluxCmdList, STMT_BREAK );
	/*astStack =*/ cg_AddConfluxStack( astContinueConfluxCmdList, STMT_CONTINUE );
	result_body = cg_Statement( astChildStmt, FALSE );
	cg_DelConfluxStack();
	cg_DelConfluxStack();

	result_body = CG_MergeResult( result_child, result_body );
	result_body = CG_MergeCmdList( result_body, astContinueConfluxCmdList );
	result_body = CG_MergeCmdList( result_body, astCondConfluxCmdList );
	astOperand = CG_NewResultOperand( result_body.astBegin );
	stCmdListAccess.leftOperand.set( astBrCmdList, astOperand );
	result = CG_MergeCmdList( result, astBreakConfluxCmdList );
	/* record  */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_DoStatement( AST astStmt, BOOL bSideEffect ){
	AST astExp;
	AST astChildStmt;
	AST astCmdList;
	AST astContinueConflux;
	AST astCondConfluxCmdList;
	AST astBreakConflux;
	AST astOperand;
	AST astBrCmdList;
	CG_RESULT result={0,0};
	CG_RESULT result_child={0,0};
	TRY;

	astCondConfluxCmdList = CG_NewConfluxCmdList( astStmt , "_conflux_start");
	astContinueConflux = CG_NewConfluxCmdList( astStmt, "_conflux_continue" );
	astBreakConflux = CG_NewConfluxCmdList( astStmt, "_conflux_break" );

	astChildStmt = stStatementAccess.do_body.get( astStmt );
		/* loop body  */
	cg_AddConfluxStack( astBreakConflux, STMT_BREAK );
	cg_AddConfluxStack( astContinueConflux, STMT_CONTINUE );

	result.astBegin = astCondConfluxCmdList;
	result.astEnd = astCondConfluxCmdList;
	result_child = cg_Statement( astChildStmt, FALSE );
	cg_DelConfluxStack();
	cg_DelConfluxStack();
	result = CG_MergeResult( result, result_child );
	result = CG_MergeCmdList( result, astContinueConflux );

	astExp = stStatementAccess.do_condExp.get( astStmt );
	result_child = CG_Expression( astExp, TRUE );
	result = CG_MergeResult( result, result_child );

		/* branch point */
	astOperand = CG_NewResultOperand( result_child.astEnd );
	astCmdList = CG_NewJudgeCmdList( astExp );
	stCmdListAccess.leftOperand.set( astCmdList, astOperand );
	result = CG_MergeCmdList( result, astCmdList );

	astBrCmdList = CG_NewBranchCmdList( astStmt );
	result = CG_MergeCmdList( result, astBrCmdList );

	result_child = CG_ExpPullPostIncDec(FALSE);
	result_child = CG_MergeCmdList( result_child, astBreakConflux );

	astOperand = CG_NewResultOperand( result_child.astBegin );
	stCmdListAccess.rightOperand.set( astBrCmdList, astOperand );

	result_child = CG_ExpPullPostIncDec(TRUE);
	result_child = CG_MergeCmdList( result_child, result.astBegin );

	astOperand = CG_NewResultOperand( result_child.astBegin );
	stCmdListAccess.leftOperand.set( astBrCmdList, astOperand );

	result = CG_MergeCmdList( result, astBreakConflux );
	/* end */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_GotoStatement( AST astStmt, BOOL bSideEffect ){
	AST astLabelStmt;
	AST astOperand;
	CG_RESULT result={0,0};
	CG_RESULT result_body={0,0};
	TRY;
	astLabelStmt = stStatementAccess.goto_statement.get( astStmt );
	result_body.astBegin = stStatementAccess.begin.get( astLabelStmt );
	if( result_body.astBegin == 0 ){
		result_body.astBegin = CG_NewConfluxCmdList( astLabelStmt, "_conflux" );
		stStatementAccess.begin.set( astLabelStmt, result_body.astBegin );
		stStatementAccess.end.set( astLabelStmt, result_body.astBegin );
	}else{
		result_body.astEnd = stStatementAccess.end.get( astLabelStmt );
	}
	astOperand = CG_NewResultOperand( result_body.astBegin );
	result.astBegin = CG_NewJumpCmdList( astStmt );
	stCmdListAccess.leftOperand.set( result.astBegin, astOperand );

	result.astEnd  = result.astBegin;
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_BreakStatement( AST astStmt, BOOL bSideEffect ){
	AST astBreakList;
	AST astStack;
	AST astOperand;
	CG_RESULT result={0,0};
	TRY;
	result.astBegin = CG_NewJumpCmdList( astStmt );
	astStack = stCgConfluxNodeStackAccess.getMax();
	astBreakList = 0;
	while( astStack >= MIN_ARRAY ){
		if( stCgConfluxNodeStackAccess.kind.get( astStack ) == STMT_BREAK ){
			if( stCgConfluxNodeStackAccess.isBreakInvalid.get( astStack ) ){
				break;
			}else{
				astBreakList = stCgConfluxNodeStackAccess.flownode.get( astStack );
				break;
			}
		}
		astStack--;
	}
	if( astBreakList > 0 ){
		astOperand = CG_NewResultOperand( astBreakList );
		stCmdListAccess.leftOperand.set( result.astBegin, astOperand );
	}
	result.astEnd = result.astBegin;
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_ContinueStatement( AST astStmt, BOOL bSideEffect ){
	AST astConList;
	AST astStack;
	AST astOperand;
	CG_RESULT result={0,0};
	TRY;
	result.astBegin = CG_NewJumpCmdList( astStmt );

	astStack = stCgConfluxNodeStackAccess.getMax();
	astConList = 0;
	while( astStack >= MIN_ARRAY ){
		if( stCgConfluxNodeStackAccess.kind.get( astStack ) == STMT_CONTINUE ){
			astConList = stCgConfluxNodeStackAccess.flownode.get( astStack );
			break;
		}
		astStack--;
	}
	if( astConList > 0 ){
		astOperand = CG_NewResultOperand( astConList );
		stCmdListAccess.leftOperand.set( result.astBegin, astOperand );
	}
	result.astEnd = result.astBegin;
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_ReturnStatement( AST astStmt, BOOL bSideEffect ){
	AST astExp;
	AST astCmdList;
	AST astOperand=0;
	CG_RESULT result={0,0};
	CG_RESULT result_body={0,0};
	TRY;
	/* body */
	astExp = stStatementAccess.return_exp.get( astStmt );
	if( astExp >= MIN_ARRAY ){
		result = CG_Expression( astExp, TRUE );
		astOperand = CG_NewResultOperand( result.astEnd );
		result_body = CG_ExpPullPostIncDec(TRUE);
		result = CG_MergeResult( result, result_body );
	}
	astCmdList = CG_NewReturnCmdList( astStmt );
	stCmdListAccess.leftOperand.set( astCmdList, astOperand );
	result = CG_MergeCmdList( result, astCmdList );
	/* record */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_DecStatement( AST astStmt, BOOL bSideEffect ){
	AST astDecl;
	CG_RESULT result={0,0};
	TRY;
	astDecl = stStatementAccess.dec_declaration.get( astStmt );
	result = CG_Declaration( astDecl );
	/* record */
	cg_recordResult( result, astStmt );
	CATCH( result );
	return result;
}
static CG_RESULT cg_Statement( AST astStmt, BOOL bSideEffect ){
	CG_RESULT result = { 0, 0 };
	switch( stStatementAccess.statmentKind.get( astStmt ) ){
	case STMT_EXP :
		return cg_ExpStatement( astStmt, bSideEffect );
	case STMT_LABEL:
		return cg_LabelStatement( astStmt, bSideEffect );
	case STMT_CASE :
		return cg_CaseStatement( astStmt, bSideEffect );
	case STMT_DEFAULT :
		return cg_DefaultStatement( astStmt, bSideEffect );
	case STMT_BLOCK   :
		return cg_BlockStatement( astStmt, bSideEffect );
	case STMT_IF:
		return cg_IfStatement( astStmt, bSideEffect );
	case STMT_SWITCH	:
		return cg_SwitchStatement( astStmt, bSideEffect );
	case STMT_FOR	:
		return cg_ForStatement( astStmt, bSideEffect );
	case STMT_WHILE	:
		return cg_WhileStatement( astStmt, bSideEffect );
	case STMT_DO:
		return cg_DoStatement( astStmt, bSideEffect );
	case STMT_GOTO	:
		return cg_GotoStatement( astStmt, bSideEffect );
	case STMT_BREAK	:
		return cg_BreakStatement( astStmt, bSideEffect );
	case STMT_CONTINUE:
		return cg_ContinueStatement( astStmt, bSideEffect );
	case STMT_RETURN	:
		return cg_ReturnStatement( astStmt, bSideEffect );
	case STMT_DEC	:
		return cg_DecStatement( astStmt, bSideEffect );
	}
	return result;
}
CG_RESULT CG_Statement( AST astStmt, BOOL bSideEffect ){
	CG_RESULT astCmdList;

	astCmdList = cg_Statement( astStmt, bSideEffect );
	return astCmdList;
}
